<template>
  <div class="camera-permissions">
    <div class="permission-header">
      <h3>摄像机权限</h3>
      <!-- 搜索框 -->
      <div class="search-container">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索摄像机名称"
          clearable
          @input="handleSearch"
          @clear="handleReset"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-button @click="handleReset" class="reset-btn">
          重置
        </el-button>
      </div>
    </div>
    
    <div class="camera-content">
      <!-- 摄像机树形结构 -->
      <div class="camera-tree-container">
        <el-tree
          ref="treeRef"
          :key="treeKey"
          :data="filteredCameraTree"
          :props="treeProps"
          :default-expanded-keys="expandedKeys"
          :default-checked-keys="checkedKeys"
          node-key="id"
          show-checkbox
          :lazy="!isSearchMode"
          :load="isSearchMode ? undefined : loadNode"
          @check="handleTreeCheck"
          :default-lazy="!isSearchMode"
        >
          <template #default="{ data }">
            <span class="tree-node">
              <el-icon class="node-icon">
                <component :is="data.isDirectory ? Folder : VideoCamera" />
              </el-icon>
              <span class="node-label">{{ data.name }}</span>
              <span v-if="!data.isDirectory" class="camera-info">
                <el-checkbox 
                  v-model="data.ptzEnable"
                  @change="handlePtzChange(data)"
                  @click.native.stop
                  class="ptz-checkbox"
                >
                可控云台
                </el-checkbox>
              </span>
            </span>
          </template>
        </el-tree>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue'
import { ElTree, ElIcon, ElInput, ElCheckbox } from 'element-plus'
import { Folder, VideoCamera, Search } from '@element-plus/icons-vue'
import { $getDeviceList, $getDeviceListByKeyword } from '@/api/device'
import { getAllMenu } from '@/api/device'
import { buildTree } from '@/utils/tree'

// Props
interface Props {
  modelValue: any[]
  cameraData?: any[]
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  cameraData: () => []
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: any[]]
}>()

// 响应式数据
const treeRef = ref()
const cameraTree = ref<any[]>([])
const expandedKeys = ref<(string | number)[]>([])
const checkedKeys = ref<number[]>([])
const searchKeyword = ref('')
const loading = ref(false)
const pendingPermissions = ref<any[]>([]) // 待处理的权限数据
const treeKey = ref(0) // 用于强制重新渲染树形组件
const isSearchMode = ref(false) // 是否处于搜索模式

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'name',
  isLeaf: 'isLeaf'
}

// 过滤后的树形数据
const filteredCameraTree = computed(() => {
  // 懒加载模式下，如果 cameraTree 为空，返回空数组让懒加载机制接管
  // Element Plus 的懒加载树形组件会在数据为空时自动触发根节点的 loadNode 方法
  return cameraTree.value
})

// 处理重置
const handleReset = async () => {
  searchKeyword.value = ''
  isSearchMode.value = false // 退出搜索模式
  
  // 重置时清空搜索相关的树形数据，让懒加载重新接管
  cameraTree.value = []
  expandedKeys.value = []
  checkedKeys.value = []
  
  // 强制重新渲染树形组件，触发懒加载
  treeKey.value++
  
  // 延迟一点时间确保组件重新渲染
  setTimeout(() => {
    if (treeRef.value) {
      treeRef.value.setExpandedKeys([])
      treeRef.value.setCheckedKeys([])
    }
  }, 100)
}

// 处理搜索（调用API搜索设备）
const handleSearch = async () => {
  if (!searchKeyword.value.trim()) {
    // 如果搜索关键词为空，重置为原始树形结构
    isSearchMode.value = false
    
    // 清空搜索相关的树形数据，让懒加载重新接管
    cameraTree.value = []
    expandedKeys.value = []
    checkedKeys.value = []
    
    // 强制重新渲染树形组件，触发懒加载
    treeKey.value++
    
    // 延迟一点时间确保组件重新渲染
    setTimeout(() => {
      if (treeRef.value) {
        treeRef.value.setExpandedKeys([])
        treeRef.value.setCheckedKeys([])
      }
    }, 100)
    return
  }
  
  try {
    loading.value = true
    isSearchMode.value = true // 设置为搜索模式
    console.log('搜索关键词:', searchKeyword.value)
    
    // 调用API搜索设备
    const response = await $getDeviceListByKeyword(searchKeyword.value)
    const searchResults = response.data || []
    
    console.log('搜索结果:', searchResults)
    
    if (searchResults.length === 0) {
      // 没有搜索结果，显示空树
      cameraTree.value = []
      checkedKeys.value = []
      return
    }
    
    // 将搜索结果转换为树形结构
    // 创建一个虚拟的根节点来包含所有搜索结果
    const searchTree = [{
      id: 'search-root',
      name: `搜索结果 (${searchResults.length}个设备)`,
      isDirectory: true,
      isLeaf: false,
      children: searchResults.map((device: any) => ({
        id: device.id,
        name: device.name,
        equId: device.equId,
        gbId: device.gbId,
        nvrId: device.nvrId,
        subEquId: device.subEquId,
        ptzEnable: device.ptzEnable || false, // 使用API返回的ptzEnable值
        isDirectory: false,
        isLeaf: true
      }))
    }]
    
    // 更新树形数据
    cameraTree.value = searchTree
    
    // 展开搜索结果节点
    expandedKeys.value = ['search-root']
    
    // 清空之前的选中状态
    checkedKeys.value = []
    
    // 强制重新渲染树形组件
    treeKey.value++
    
    // 确保树形组件正确显示
    setTimeout(() => {
      if (treeRef.value) {
        treeRef.value.setExpandedKeys(['search-root'])
      }
    }, 100)
    
  } catch (error) {
    console.error('搜索设备失败:', error)
    // 搜索失败时，重置为原始树形结构
    isSearchMode.value = false
    
    // 清空搜索相关的树形数据，让懒加载重新接管
    cameraTree.value = []
    expandedKeys.value = []
    checkedKeys.value = []
    
    // 强制重新渲染树形组件，触发懒加载
    treeKey.value++
    
    // 延迟一点时间确保组件重新渲染
    setTimeout(() => {
      if (treeRef.value) {
        treeRef.value.setExpandedKeys([])
        treeRef.value.setCheckedKeys([])
      }
    }, 100)
  } finally {
    loading.value = false
  }
}

// 获取目录下所有摄像头的ID
const getCameraIdsInDirectory = (node: any): number[] => {
  const cameraIds: number[] = []
  
  const traverse = (n: any) => {
    if (!n.isDirectory && n.id) {
      cameraIds.push(n.id)
    }
    if (n.children) {
      n.children.forEach(traverse)
    }
  }
  
  traverse(node)
  return cameraIds
}

// 处理树形选择
const handleTreeCheck = (_data: any, checked: { checkedKeys: number[], checkedNodes: any[], halfCheckedKeys: number[] }) => {
  const newCheckedKeys = [...checked.checkedKeys]
  
  // 处理所有选中的目录节点
  checked.checkedNodes.forEach(node => {
    if (node.isDirectory) {
      // 选中的目录，自动选中其下所有摄像头
      const cameraIds = getCameraIdsInDirectory(node)
      cameraIds.forEach(cameraId => {
        if (!newCheckedKeys.includes(cameraId)) {
          newCheckedKeys.push(cameraId)
        }
      })
    }
  })
  
  // 处理取消选中的目录节点
  const previouslyChecked = checkedKeys.value
  const currentlyChecked = checked.checkedKeys
  
  // 找出被取消选中的节点
  const uncheckedNodes = previouslyChecked.filter(id => !currentlyChecked.includes(id))
  
  uncheckedNodes.forEach(nodeId => {
    // 在懒加载模式下，优先从树组件中获取节点数据
    let node = null
    if (treeRef.value) {
      const treeNode = treeRef.value.getNode(nodeId)
      if (treeNode) {
        node = treeNode.data
      }
    }
    
    // 如果从树组件中找不到，尝试从 cameraTree 中查找
    if (!node) {
      node = findNodeInTree(cameraTree.value, nodeId)
    }
    
    console.log(`处理取消选中的节点: ID=${nodeId}, 找到节点:`, node)
    
    if (node && node.isDirectory) {
      // 取消选中的目录，自动取消选中其下所有摄像头
      const cameraIds = getCameraIdsInDirectory(node)
      console.log(`目录 ${node.name} 下的摄像机IDs:`, cameraIds)
      cameraIds.forEach(cameraId => {
        const index = newCheckedKeys.indexOf(cameraId)
        if (index > -1) {
          newCheckedKeys.splice(index, 1)
        }
        // 同时取消这些摄像机的PTZ权限
        let cameraNode = null
        if (treeRef.value) {
          const treeNode = treeRef.value.getNode(cameraId)
          if (treeNode) {
            cameraNode = treeNode.data
          }
        }
        if (!cameraNode) {
          cameraNode = findNodeInTree(cameraTree.value, cameraId)
        }
        if (cameraNode && cameraNode.ptzEnable) {
          cameraNode.ptzEnable = false
          console.log(`取消选中目录，自动取消PTZ权限: ${cameraNode.name} (ID: ${cameraNode.id})`)
        }
      })
    } else if (node && !node.isDirectory) {
      // 取消选中的摄像机，自动取消PTZ权限
      console.log(`取消选中的摄像机: ${node.name}, 当前PTZ状态: ${node.ptzEnable}`)
      if (node.ptzEnable) {
        node.ptzEnable = false
        console.log(`取消选中摄像机，自动取消PTZ权限: ${node.name} (ID: ${node.id})`)
      }
    } else {
      console.warn(`未找到节点: ID=${nodeId}`)
    }
  })
  
  checkedKeys.value = newCheckedKeys
  emitUpdate()
}

// 处理PTZ控制变化（支持懒加载）
const handlePtzChange = (data: any) => {
  console.log('PTZ状态变化:', data.name, data.ptzEnable, '摄像机ID:', data.id)
  console.log('当前选中的摄像机:', checkedKeys.value)
  
  // 如果启用了PTZ，确保摄像机被选中
  if (data.ptzEnable && !checkedKeys.value.includes(data.id)) {
    checkedKeys.value.push(data.id)
    console.log(`启用PTZ，自动选中摄像机: ${data.name} (ID: ${data.id})`)
    console.log('更新后的选中列表:', checkedKeys.value)
    
    // 手动更新树形组件的选中状态
    if (treeRef.value) {
      treeRef.value.setCheckedKeys(checkedKeys.value)
    }
  }
  
  emitUpdate()
}

// 发出更新事件（支持懒加载）
const emitUpdate = () => {
  const result: any[] = []
  
  // 遍历选中的节点
  checkedKeys.value.forEach(nodeId => {
    // 在懒加载模式下，需要从树组件中获取节点数据
    let node = null
    if (treeRef.value) {
      const treeNode = treeRef.value.getNode(nodeId)
      if (treeNode) {
        node = treeNode.data
      }
    }
    
    // 如果从树组件中找不到，尝试从 cameraTree 中查找
    if (!node) {
      node = findNodeInTree(cameraTree.value, nodeId)
    }
    
    if (node) {
      if (node.isDirectory) {
        // 目录权限
        result.push({
          directoryId: nodeId,
          directoryName: node.name,
          isDirectory: true,
          ptzEnable: false
        })
      } else {
        // 摄像机权限
        result.push({
          cameraId: node.id,
          name: node.name,
          ptzEnable: node.ptzEnable || false,
          isDirectory: false,
          nvrId: node.nvrId || 0,
          subEquId: node.subEquId || 0
        })
      }
    }
  })
  
  emit('update:modelValue', result)
}

// 在树中查找节点
const findNodeInTree = (nodes: any[], nodeId: number): any => {
  for (const node of nodes) {
    if (node.id === nodeId) {
      return node
    }
    if (node.children) {
      const found = findNodeInTree(node.children, nodeId)
      if (found) return found
    }
  }
  return null
}

// 在树中查找摄像机节点（支持懒加载）
const findCameraNodeInTree = (nodes: any[], cameraId: number | string): any => {
  for (const node of nodes) {
    if (!node.isDirectory && (node.equId == cameraId || node.gbId == cameraId || node.id == cameraId)) {
      return node
    }
    if (node.children && node.children.length > 0) {
      const found = findCameraNodeInTree(node.children, cameraId)
      if (found) return found
    }
  }
  return null
}

// 在懒加载树中查找摄像机节点（递归查找所有已加载的节点）
const findCameraNodeInLazyTree = (cameraId: number | string): any => {
  // 使用 Element Plus Tree 的方法获取所有节点
  if (treeRef.value) {
    const allNodes = treeRef.value.store._getAllNodes()
    for (const node of allNodes) {
      if (node.data && !node.data.isDirectory) {
        // cameraPrivileges中的cameraId需要与设备列表中的id字段匹配
        if (node.data.id == cameraId) {
          return node.data
        }
      }
    }
  }
  return null
}

// 加载目录下的设备
const loadDevicesByMenu = async (menuId: number): Promise<any[]> => {
  try {
    const response = await $getDeviceList(menuId.toString(),true)
    return response.data || []
  } catch (error) {
    console.error('加载设备列表失败:', error)
    return []
  }
}


// 懒加载节点数据
const loadNode = async (node: any, resolve: (data: any[]) => void) => {
  try {
    // 如果是根节点，返回菜单（文件夹）列表
    if (node.level === 0) {
      try {
        const response = await getAllMenu()
        const menuData = response.data || []
        
        if (menuData.length === 0) {
          resolve([])
          return
        }
        
        // 构建树形结构
        const builtTree = buildTree(menuData)
        
        // 为每个菜单节点添加懒加载标识
        const rootNodes = builtTree.map(menu => ({
          id: menu.id,
          name: menu.name,
          isDirectory: true,
          isLeaf: false, // 菜单不是叶子节点，可能有子菜单或设备
          children: [] // 初始为空，等待懒加载
        }))
        
        // 更新 cameraTree 数据
        cameraTree.value = rootNodes
        
        resolve(rootNodes)
        return
      } catch (apiError) {
        console.error('getAllMenu API调用失败:', apiError)
        resolve([])
        return
      }
    }
    
    // 如果是菜单节点，加载其下的设备和子菜单
    if (node.data.isDirectory) {
      const menuId = node.data.id
      
      // 加载设备
      const devices = await loadDevicesByMenu(menuId)
      const deviceNodes = devices.map(device => ({
        id: device.id,
        name: device.name,
        equId: device.equId,
        gbId: device.gbId,
        nvrId: device.nvrId,
        subEquId: device.subEquId,
        ptzEnable: false,
        isDirectory: false,
        isLeaf: true // 设备是叶子节点
      }))
      
      // 获取所有菜单，查找子菜单
      const allMenusResponse = await getAllMenu()
      const allMenus = allMenusResponse.data || []
      const childMenus = allMenus.filter((menu: any) => menu.parentId === menuId)
      
      const childMenuNodes = childMenus.map((menu: any) => ({
        id: menu.id,
        name: menu.name,
        isDirectory: true,
        isLeaf: false,
        children: []
      }))
      
      // 合并子菜单和设备，子目录在前，设备在后
      const allChildren = [...childMenuNodes, ...deviceNodes]
      
      // 节点加载完成后，重新应用权限
      setTimeout(() => {
        console.log('节点加载完成，重新应用权限')
        // 确保有权限数据时才应用
        if (pendingPermissions.value.length > 0 || (props.modelValue && props.modelValue.length > 0)) {
          applyPendingPermissions()
        }
      }, 100)
      
      resolve(allChildren)
    } else {
      // 设备节点没有子节点
      resolve([])
    }
  } catch (error) {
    console.error('懒加载节点失败:', error)
    resolve([])
  }
}

// 加载摄像机树形结构（懒加载模式下简化）
const loadCameraTree = async () => {
  try {
    loading.value = true
    console.log('开始加载摄像机树形结构')
    
    // 懒加载模式下，不设置cameraTree为空数组
    // 而是通过强制重新渲染来触发懒加载
    // cameraTree.value = [] // 删除这行，避免清空文件夹
    
    // 强制重新渲染树形组件，触发懒加载
    treeKey.value++
    
    // 延迟处理权限数据，确保懒加载已经开始
    setTimeout(() => {
      console.log('检查是否有待处理的权限数据:', pendingPermissions.value.length)
      // 如果有待处理的权限数据，现在处理它们
      if (pendingPermissions.value.length > 0) {
        console.log('处理待处理的权限数据')
        // 不立即应用，等待用户交互加载数据
        console.log('权限数据已设置，等待用户交互加载数据后应用')
      }
    }, 1000) // 增加延迟时间确保懒加载完成
  } catch (error) {
    console.error('加载摄像机树失败:', error)
    cameraTree.value = []
  } finally {
    loading.value = false
  }
}

// 处理懒加载完成后的权限设置
const applyPendingPermissions = () => {
  // 如果没有待处理权限，尝试从props.modelValue重新获取权限数据
  let permissionsToApply = pendingPermissions.value
  if (permissionsToApply.length === 0 && props.modelValue && props.modelValue.length > 0) {
    console.log('没有待处理权限，从props.modelValue重新获取权限数据')
    permissionsToApply = props.modelValue.filter(item => item.cameraId && item.cameraId > 0)
  }
  
  if (permissionsToApply.length === 0) {
    return
  }
  
  console.log('开始应用摄像机权限数据:', permissionsToApply)
  
  const keys: number[] = []
  let foundNodes = 0
  
  permissionsToApply.forEach(item => {
    // 查找对应的摄像机节点ID（使用懒加载查找方法）
    const cameraNode = findCameraNodeInLazyTree(item.cameraId)
    if (cameraNode) {
      keys.push(cameraNode.id)
      // 更新PTZ状态 - 直接使用cameraPrivileges中的ptzEnable值
      cameraNode.ptzEnable = item.ptzEnable || false
      foundNodes++
      console.log(`添加摄像机权限: ${cameraNode.name} (ID: ${cameraNode.id}), PTZ: ${cameraNode.ptzEnable}`)
    } else {
      console.warn(`未找到摄像机节点: cameraId=${item.cameraId}`)
    }
  })
  
  console.log(`找到 ${foundNodes} 个摄像机节点，总共 ${permissionsToApply.length} 个权限项`)
  
  checkedKeys.value = keys
  console.log('最终选中的节点ID列表:', checkedKeys.value)
  
  // 手动设置树形组件的选中状态
  if (treeRef.value && keys.length > 0) {
    console.log('设置树形组件选中状态:', keys)
    treeRef.value.setCheckedKeys(keys)
  }
}

// 处理权限数据
const processPermissions = (permissions: any[]) => {
  console.log('收到摄像机权限数据:', permissions)
  
  if (!permissions || permissions.length === 0) {
    checkedKeys.value = []
    console.log('权限数据为空，清空选中状态')
    return
  }
  
  // 过滤掉无效的权限数据（cameraId为0）
  const validPermissions = permissions.filter(item => {
    return item.cameraId && item.cameraId > 0
  })
  
  console.log('过滤后的有效权限数据:', validPermissions)
  
  if (validPermissions.length === 0) {
    checkedKeys.value = []
    console.log('没有有效的权限数据，清空选中状态')
    return
  }
  
  // 懒加载模式下，权限数据需要延迟处理
  // 因为树形结构还没有完全加载
  pendingPermissions.value = [...validPermissions]
  console.log('设置待处理权限数据:', pendingPermissions.value)
  
  // 不立即应用权限，等待数据加载完成后再应用
  console.log('权限数据已设置，等待数据加载完成后应用')
}

// 监听传入的选中状态
watch(
  () => props.modelValue,
  (newValue) => {
    processPermissions(newValue)
  },
  { immediate: true }
)

// 清空所有数据
const clearAllData = () => {
  cameraTree.value = []
  expandedKeys.value = []
  checkedKeys.value = []
  searchKeyword.value = ''
  pendingPermissions.value = []
  // 不重置treeKey，保持重新渲染能力
}

// 重新加载数据
const reloadData = () => {
  // 清空当前数据
  clearAllData()
  
  // 强制重新渲染树形组件
  treeKey.value++
  
  // 延迟重新加载数据，确保组件完全重置
  setTimeout(() => {
    // 直接重新加载，不调用loadCameraTree避免错误
  }, 200)
}

// 暴露方法给父组件
defineExpose({
  clearAllData,
  reloadData
})

// 组件挂载时初始化数据
onMounted(async () => {
  // 延迟一点时间确保组件完全渲染
  setTimeout(() => {
    loadCameraTree()
  }, 100)
})
</script>

<style scoped>
.camera-permissions {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.permission-header {
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #e4e7ed;
}

.permission-header h3 {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.search-container {
  margin-bottom: 0;
  display: flex;
  gap: 12px;
  align-items: center;
}

.search-container .el-input {
  flex: 1;
}

.reset-btn {
  flex-shrink: 0;
}

.camera-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.camera-tree-container {
  flex: 1;
  overflow-y: auto;
  padding-right: 8px;
}

.tree-node {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  justify-content: space-between;
}

.node-icon {
  font-size: 14px;
  color: #606266;
}

.node-label {
  font-size: 14px;
  color: #303133;
  flex: 1;
}

.camera-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ptz-checkbox {
  font-size: 12px;
}

:deep(.el-tree-node__content) {
  height: 32px;
  padding: 0 8px;
}

:deep(.el-tree-node__content:hover) {
  background-color: #f5f7fa;
}
</style>
